package com.whmskj.xjlhsc.schedul;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.whmskj.xjlhsc.entity.EquipmentMtnPlanAllocation;
import com.whmskj.xjlhsc.entity.WbPlan;
import com.whmskj.xjlhsc.entity.WbPlanDetal;
import com.whmskj.xjlhsc.entity.WbRecord;
import com.whmskj.xjlhsc.enums.ScEnums;
import com.whmskj.xjlhsc.jitapi.entity.Device;
import com.whmskj.xjlhsc.jitapi.mapper.DeviceMapper;
import com.whmskj.xjlhsc.jitapi.mapper.InventoryMapper;
import com.whmskj.xjlhsc.service.EquipmentMtnPlanAllocationService;
import com.whmskj.xjlhsc.service.WbPlanService;
import com.whmskj.xjlhsc.service.WbRecordService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.whmskj.xjlhsc.enums.ScEnums.SCWBTJZT.OVERDUE;
import static com.whmskj.xjlhsc.enums.ScEnums.SCWBZT.GENED;

/**
 * @BelongsProject: XJLHSC
 * @BelongsPackage: com.whmskj.xjlhsc.schedul
 * @Author: lk
 * @CreateTime: 2025-06-16
 * @Description: 任务任务生成
 * @Version: 1.0
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class WbTaskGeneratorTask implements Task {

    private final WbPlanService wbPlanService;
    private final EquipmentMtnPlanAllocationService equipmentMtnPlanAllocationService;
    private final DeviceMapper deviceMapper;
    private final WbRecordService wbRecordService;
    private final InventoryMapper inventoryMapper;

    /**
     * 每天00：00：00执行任务生成
     */
    @Override
    @Scheduled(cron = "0 0 0 * * ?")
    public void taskGenerate() {
        LocalDate nowDate = LocalDate.now();
        //判断当前日期是哪个绩效月
        String jxy = inventoryMapper.getMonthByYmd(nowDate.toString());
        LambdaQueryWrapper<WbPlan> qe = Wrappers.lambdaQuery();
        qe.eq(WbPlan::getYmDate, jxy).eq(WbPlan::getState, GENED.getCode());
        List<WbPlan> wbPlans = wbPlanService.list(qe);

        if (CollectionUtil.isEmpty(wbPlans)) return;
        //查询维保任务分配人
        LambdaQueryWrapper<EquipmentMtnPlanAllocation> qe1 = Wrappers.lambdaQuery();
        qe1.in(EquipmentMtnPlanAllocation::getWbPlanId, wbPlans.stream().map(WbPlan::getMaintenancePlanId).toList());
        Map<Long, List<EquipmentMtnPlanAllocation>> allocationGroup = equipmentMtnPlanAllocationService.list(qe1).stream().collect(Collectors.groupingBy(EquipmentMtnPlanAllocation::getWbPlanId));
        //查询所有设备
        Map<Integer, Device> deviceIdMapI = deviceMapper.allDevice().stream().collect(Collectors.toMap(Device::getDeviceId, Function.identity()));

        List<WbRecord> saveRecordList = new java.util.ArrayList<>();
        for (WbPlan wbPlan : wbPlans) {
            //分配人
            List<EquipmentMtnPlanAllocation> allocations = allocationGroup.get(wbPlan.getMaintenancePlanId());
            allocations.forEach(cur -> cur.setEquipmentIdsList(Arrays.stream(cur.getEquipmentIds().split(",")).toList()));
            //查询今天计划需要开启维保的机台
            List<WbPlanDetal> wbPlanDetals = wbPlanService.getDeviceListWithToday(wbPlan.getMaintenancePlanId(), nowDate);
            for (WbPlanDetal wbPlanDetal : wbPlanDetals) {
                String deviceId = wbPlanDetal.getValue();
                Device device = deviceIdMapI.get(Integer.parseInt(deviceId));
                //查询该设备的维保任务分配人
                String userCode = getAllocations(allocations, deviceId);
                WbRecord wbRecord = new WbRecord();
                wbRecord.setPlanId(wbPlan.getMaintenancePlanId());
                wbRecord.setDeviceId(Integer.parseInt(deviceId));
                wbRecord.setPlanDate(new Date());
                wbRecord.setExecutor(userCode);
                wbRecord.setWbTjState(ScEnums.SCWBTJZT.UNPROCESSED.getCode());
                wbRecord.setWbJdState(ScEnums.SCWBJDZT.UNPROCESSED.getCode());
                //wbRecord.setWbRecordState(UNPROCESSED.getCode());
                saveRecordList.add(wbRecord);
            }
        }
        wbRecordService.saveBatch(saveRecordList);
        //逾期状态判定
        LambdaQueryWrapper<WbRecord> qe3 = new LambdaQueryWrapper<>();
        qe3.in(WbRecord::getWbTjState, ScEnums.SCWBTJZT.UNPROCESSED.getCode(), OVERDUE.getCode()).lt(WbRecord::getPlanDate, LocalDate.now().toString());
        List<WbRecord> overdueList = wbRecordService.list(qe3);
        if (CollectionUtil.isNotEmpty(overdueList)) {
            for (WbRecord wbRecord : overdueList) {
                wbRecord.setWbTjState(OVERDUE.getCode());
                wbRecord.setOverdueDay(TimeUnit.DAYS.convert(LocalDate.now().atStartOfDay().toInstant(java.time.ZoneOffset.of("+8")).getEpochSecond() - wbRecord.getPlanDate().getTime(), TimeUnit.MILLISECONDS) + "");
            }
            wbRecordService.updateBatchById(overdueList);
        }

    }

    private String getAllocations(List<EquipmentMtnPlanAllocation> allocations, String deviceId) {
        for (EquipmentMtnPlanAllocation allocation : allocations) {
            if (allocation.getEquipmentIdsList().contains(deviceId)) {
                return allocation.getUserId();
            }
        }
        return null;
    }

}
